热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

更多|表里_busybox的实现原理分析(C语言实现简易版的busybox)

篇首语:本文由编程笔记#小编为大家整理,主要介绍了busybox的实现原理分析(C语言实现简易版的busybox)相关的知识,希望对你有一定的参考价值。1、li

篇首语:本文由编程笔记#小编为大家整理,主要介绍了busybox的实现原理分析(C语言实现简易版的busybox)相关的知识,希望对你有一定的参考价值。



1、linux中实现命令的两种方式

1.1、命令都是单独的可执行程序

aston:~$ ls -l /bin/ls
-rwxr-xr-x 1 root root 138208 28 2022 /bin/ls
aston:~$
aston:~$ ls -l /bin/mkdir
-rwxr-xr-x 1 root root 68096 28 2022 /bin/mkdir
aston:~$
aston:~$ file /bin/ls
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=897f49cafa98c11d63e619e7e40352f855249c13, for GNU/Linux 3.2.0, stripped


(1)在linux的根文件系统中,系统自带的命令放在"/bin、/sbin"目录中,用户的命令放在"/usr/bin、/usr/sbin"目录中;
(2)用"ls -l"可知每个命令都是二进制文件,用"file"命令查看可知每个命令都是可执行文件;
(3)命令都是单独的可执行程序,这种方式一般都是Ubuntu、Centos、服务器的linux系统采用,部署在硬件资源比较充足的设备里;



1.2、命令是指向busybox的符号链接



(1)用"ls -l"可知每个命令都是符号链接,指向busybox;
(2)这种方式一般是嵌入式设备采用;



1.3、两种实现方式的对比



(1)每个命令都是单独的可执行程序:这种方式要求的资源更多,但是命令支持的功能也更丰富;
(2)用符号链接和busybox实现命令:busybox占用的空间明显小于所有单独命令可执行程序占用空间之和,节省更多的资源,但是busybox的命令都是裁剪过的,只支持命令中常用的选项;
(3)busybox适合嵌入式设备,支持必要的命令,而且占用的空间小,嵌入式设备flash和内存一般都不富裕;
(4)命令是单独可执行程序的方式:更适合在电脑、服务器上运行的linux系统,flash和内存等硬件资源都比较充裕,更注重性能和命令的完整;



2、busybox介绍

2.1、为什么需要busybox



(1)busybox集成了常用的所有命令,可以很方便的构建文件系统。假设现在要构建文件系统,如果没有busybox,则需要去下载"ls、cd、mkdir······"每个命令的源码再编译,工作量很大且很繁琐;
(2)busybox高度可裁剪,需要支持什么命令就配置busybox编译哪些命令的源码,有效减小busybox的体积,节省空间;



2.2、busybox的源码获取



官网地址:www.busybox.net



2.3、busybox的两种使用方式



(1)符号链接:建立符号链接指向busybox,为每个命令建立一个符号链接;
(2)直接调用busybox,比如:"busybox ls"的效果和直接执行"ls"命令是相同的;



3、C语言实现简易版busybox

3.1、源码

#include
#include
#include
//计算数组的成员个数
#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
//实现ls命令功能
int my_ls_main(int argc, char * argv[])

char bufCmd[256] = 0;
sprintf(bufCmd, "ls %s", argv[1]);
system(bufCmd);
return 0;

//实现mkdir命令功能
int my_mkdir_main(int argc, char * argv[])

char bufCmd[256] = 0;
sprintf(bufCmd, "mkdir %s", argv[1]);
system(bufCmd);
return 0;

//busybox的说明函数
int my_help_main(int argc, char * argv[])

printf("busybox only support commond:ls and mkdir\\n");
return 0;

//支持的命令列表
const char *applet_names[] =

"my_ls",
"my_mkdir",
"--help",
"-h"
;
//每个命令对应的实现函数,顺序要和applet_names数组的顺序一一对应
int (*const applet_main[])(int argc, char * argv[]) =

my_ls_main,
my_mkdir_main,
my_help_main,
my_help_main,
;
int main(int argc, char * argv[])

int i = 0;
char *cmdBuf = malloc(256);
int start_index = 0;
memset(cmdBuf, 0, sizeof(cmdBuf));
//打印接收到的命令
#if 0
while(i < argc)

printf("argv[%d] &#61; %s \\n", i, argv[i]);
i&#43;&#43;;

#endif
//如果是直接调用的busybox需要特殊处理
if(strcmp(argv[0], "my_busybox") &#61;&#61; 0)

start_index &#61; 1;

//在支持的命令列表里查找是否支持该命令
for(i &#61; 0; i < ARRAY_SIZE(applet_names); i&#43;&#43;)

if (strcmp(argv[start_index], applet_names[i]) &#61;&#61; 0)

applet_main[i](argc, argv);
break;


//查找不到输入的命令则不支持该命令
if(i &#61;&#61; ARRAY_SIZE(applet_names))

printf("command not found\\n");
return -1;

return 0;


3.2、代码的编译和使用

[root#]$ ls -l
total 16
-rwxr-xr-x 1 310793 domain_users 8352 Nov 15 16:25 my_busybox
lrwxrwxrwx 1 310793 domain_users 10 Nov 15 16:25 my_ls -> my_busybox
lrwxrwxrwx 1 310793 domain_users 10 Nov 15 16:26 my_mkdir -> my_busybox
-rwxrw---- 1 310793 domain_users 1857 Nov 15 16:31 test.c


(1)为了避免与系统中的busybox冲突&#xff0c;将可执行程序命名为my_busybox&#xff1b;
(2)本简易版busybox仅支持ls和mkdir命令&#xff0c;所以创建my_ls和my_mkdir命令执行my_busybox&#xff1b;
(3)将代码所在目录导出到环境变量PATH中&#xff0c;可以自动查找到刚才构建的命令(export PATH&#61;命令所在路径:$PATH);



3.3、代码执行效果

[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ gcc test.c -o my_busybox
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
my_busybox my_ls my_mkdir test.c
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_mkdir 112233
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
112233 my_busybox my_ls my_mkdir test.c
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_busybox my_ls ./
112233 my_busybox my_ls my_mkdir test.c
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_busybox -h
busybox only support commond:ls and mkdir
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$
[310793&#64;yanfa204_ubuntu18-jk128:weops 222]$ my_busybox --help
busybox only support commond:ls and mkdir

4、busybox实现框架分析


(1)busybox是个可执行程序&#xff0c;程序入口是main函数&#xff0c;在appletlib.c文件中&#xff1b;
(2)在main中只是实现逻辑控制&#xff0c;并不执行具体的功能&#xff0c;会把输入的指令进行解析&#xff0c;查找指令对应的函数去执行&#xff1b;
(3)在代码中有两个重要的数组&#xff0c;applet_main是函数指针数组&#xff0c;里面是每个命令对应的函数的函数指针&#xff0c;applet_names是保存的命令的字符串&#xff0c;两个数组的元素是一一对应的&#xff1b;
(4)将传递进来的命令先和applet_names数组进行比对&#xff0c;如果匹配上就拿数组下标去applet_main数组取的命令对应的函数并执行&#xff1b;
(5)每个命令都有对应的函数&#xff0c;比如&#xff1a;ls对应"ls_main"函数&#xff0c;cd命令对应"cd_main"函数&#xff1b;



推荐

再难的项目都是基础知识的复杂运用&#xff0c;基础是最重要的。给大家推荐一个学校嵌入式知识的网站&#xff0c;博主在大学时候学习嵌入式知识、找工作的时候都在用这个网站&#xff0c;网站里有C语言、Linux等等的笔试题、面试常问问题等等知识&#xff0c;无论是学习基础知识、面试刷题、交流工作经验都是不错的选择。大家一起进步&#xff0c;欢迎留言交流。
链接&#xff1a;学习神器跳转



推荐阅读
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • Python项目实战10.2:MySQL读写分离性能优化
    本文介绍了在Python项目实战中进行MySQL读写分离的性能优化,包括主从同步的配置和Django实现,以及在两台centos 7系统上安装和配置MySQL的步骤。同时还介绍了创建从数据库的用户和权限的方法。摘要长度为176字。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了在CentOS 7.x上进行端口映射配置的方法,通过修改内核和配置防火墙实现端口映射。作者分享了自己使用华为服务器进行端口映射的经验,发现网速比直连还快且稳定。详细的配置过程包括开启系统路由模式功能、设置IP地址伪装、设置端口映射等。同时,还介绍了如何监听本地端口的tcp请求,以及删除规则和开放的端口的方法。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 网卡工作原理及网络知识分享
    本文介绍了网卡的工作原理,包括CSMA/CD、ARP欺骗等网络知识。网卡是负责整台计算机的网络通信,没有它,计算机将成为信息孤岛。文章通过一个对话的形式,生动形象地讲述了网卡的工作原理,并介绍了集线器Hub时代的网络构成。对于想学习网络知识的读者来说,本文是一篇不错的参考资料。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
author-avatar
小啊丌-619
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有